<?php
class __APPLICATION
{
	private static $_instance;
	public $appConfig = array();
	protected $_settingInfo = array();
	private $_isSettup = false;
	public $db;
	public $request;
	public $session;
	public $cookie;
	public $server;

	public static function getInstance() {
		if(!self::$_instance) self::$_instance = new self();
		return self::$_instance;
	}

	public function run() {
		if (!$this->_isSetup) {
			$this->_setupApplication();
		}

		$this->request->setControllerKey('controller');
		$this->request->setModuleKey('module');
		$this->request->setActionKey('action');

		$controller = $this->request->getControllerName();
		$module = $this->request->getModuleName();
		$action = $this->request->getActionName();

		if (!empty($action)) {
			$controllerClass = $controller . '_' . $module . '_' . $action;
		} else {
			$controllerClass = $controller . '_' . $module;
		}

		if (class_exists($controllerClass, false) || interface_exists($controllerClass, false)) {
			return;
		}

		$file = ROOT . '/' . APP_CONTROLLER_DIR . '/' . str_replace('_', '/', $controllerClass) . '.php';
		//die($file);
		// Check security file
		if (preg_match('/[^a-z0-9\\/\\\\_.:-]/i', $filename)) {
			throw new __EXCEPTION('Security check: Illegal character in filename');
		}

		if (!file_exists($file)) {
			// 404     
			echo __LAYOUT::getInstance()->loadLayout('404'); die;
//			throw new __EXCEPTION("File \"$file\" does not exist or class \"$controllerClass\" was not found in the file");
		}

		require_once($file);
	}

	private function _setupApplication() {
		$this->_loadConfigFile();

		if (!empty($this->_settingInfo)) {
			$this->_setup($this->_settingInfo['appSetup']);
		} else {
			throw new Exception_Application('Error when loading config file!!!');
		}

		$this->db = $this->_setupDatabase($this->_settingInfo['databaseConnectInfo']);
		$this->request = $this->getRequest();
		$this->server = $this->getServer();
		$this->cookie = $this->getCookie();
		$this->session = $this->getSession();

		$this->_isSetup = true;
	}

	private function _loadConfigFile() {
		$settingFile = ROOT . '/apps/settings.php';
		if (file_exists($settingFile)) {
			require_once ($settingFile);
			$this->_settingInfo['databaseConnectInfo'] = $databaseConnectInfo;
			$this->_settingInfo['debugs'] = $debugs;
			$this->_settingInfo['appSetup'] = $appSetup;
		} else {
			throw new __EXCEPTION('Can not load setting file: "' . $settingFile . '"');
		}
	}

	private function _setup($configArray = array()) {
		$this->_loadDefaultSetting();
		foreach ($configArray as $settingName => $settingValue) {
			if (!empty($settingName)) $this->addSetting($settingName, $settingValue);
		}

		return $this;
	}

	public function addSetting($settingName, $settingValue = '')
	{
		$this->_appConfig[$settingName] = $settingValue;
	}

	public function getSetting($settingName = '')
	{
		if (!$this->appConfig[$settingName] OR empty ($settingName) OR !$settingName) return false;
		return $this->appConfig[$settingName];
	}

	private function _loadDefaultSetting()
	{}

	public function __construct() {
	}

	private function _setupDatabase($databaseInfo = FALSE) {
		if (!$databaseInfo) {
			$databaseInfo = $this->_appConfig['database'];
		}
		$database = __DATABASE::getInstance($databaseInfo);

		return $database;
	}

	public function getRequest()
	{
		return __REQUEST::getInstance();
	}

	public function getCookie()
	{
		return __COOKIE::getInstance();
	}

	public function getSession()
	{
		return __SESSION::getInstance();
	}

	public function getServer()
	{
		return __SYSTEM::getInstance();
	}

	public function loadGroupFunction($groupName = '') {
		$group = array(
			'string' => 'string',
			'bot' => 'bot',
			'ip' => 'ip',
			'dom' => 'simpleHtmlDom',
			'time' => 'time',
			'date' => 'time',
			'url' => 'url',
		);

		if (!in_array($groupName, array_keys($group))) return FALSE;
		$function_group_name = $group[$groupName];

		if (file_exists(CORE_APP_DIR . '/' . 'functions' . '/' . $function_group_name . '.php')) {
			require_once (CORE_APP_DIR . '/' . 'functions' . '/' . $function_group_name . '.php');
		}
	}

	public function getPath() {
		if (!empty($this->request->siteUrl)) {
			return $this->request->siteUrl;
		}

		return '';
	}

	public function getPathTheme() {
		$layoutGroup = __LAYOUT::getInstance()->getGroupLayout();
		if (!empty($this->request->baseSiteurl)) {
			return $this->request->baseSiteurl . '/layout/' . $layoutGroup;
		}

		return '';
	}

	public function getFullPathTheme() {
		$layoutGroup = __LAYOUT::getInstance()->getGroupLayout();
		if (!empty($this->request->siteUrl)) {
			return $this->request->siteUrl . '/layout/' . $layoutGroup;
		}

		return '';
	}

	public function getPathCss() {
		$layoutGroup = __LAYOUT::getInstance()->getGroupLayout();
		if (!empty($this->request->baseSiteurl)) {
			return $this->request->baseSiteurl . '/layout/' . $layoutGroup . '/css';
		}

		return '';
	}

	public function getFullPathCss() {
		$layoutGroup = __LAYOUT::getInstance()->getGroupLayout();
		if (!empty($this->request->siteUrl)) {
			return $this->request->siteUrl . '/layout/' . $layoutGroup . '/css';
		}

		return '';
	}

	public function getPathJs() {
		$layoutGroup = __LAYOUT::getInstance()->getGroupLayout();
		if (!empty($this->request->baseSiteurl)) {
			return $this->request->baseSiteurl . '/layout/' . $layoutGroup . '/js';
		}

		return '';
	}

	public function getFullPathJs() {
		$layoutGroup = __LAYOUT::getInstance()->getGroupLayout();
		if (!empty($this->request->siteUrl)) {
			return $this->request->siteUrl . '/layout/' . $layoutGroup . '/css';
		}

		return '';
	}

	public function getPathImg() {
		$layoutGroup = __LAYOUT::getInstance()->getGroupLayout();
		if (!empty($this->request->baseSiteurl)) {
			return $this->request->baseSiteurl . '/layout/' . $layoutGroup . '/images';
		}

		return '';
	}

	public function getFullPathImg() {
		$layoutGroup = __LAYOUT::getInstance()->getGroupLayout();
		if (!empty($this->request->siteUrl)) {
			return $this->request->siteUrl . '/layout/' . $layoutGroup . '/images';
		}

		return '';
	}
}